package com.shenmazong.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.shenmazong.utils.ResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

/**
 * @author Qi
 * @version 1.0
 * @description TODO
 * @date 2021/8/24 15:34
 */
@Slf4j
@Component
public class OssUploadTemplate {
     /*
        ! ossObject对象使用完毕后必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。关闭方法如下 !
     */

    /** 上传到本地的路径 */
    private final static String LOCAL_PATH = "D://img//";


    /**
     * 创建oss实例，每次调用都创建
     */
    public OSS CreateOssClient(){
        return new OSSClientBuilder().build(ConstantYml.ENDPOINT, ConstantYml.ACCESSKEYID, ConstantYml.ACCESSKEYSECRET);
    }

    /**
     * @return com.john.utils.ResultResponse
     * @description 使用oss上传文件，流式上传，适合上传大文件，大图片，练习
     * @params [file]
     * @author -还怕大雨吗
     * @date 2021/8/18 8:20
     */
    public ResultResponse uploadFileObjectStorage(MultipartFile file) {
        if (file == null ) {
            log.error("当前上传的文件为空");
            return ResultResponse.FAILED("当前上传的文件为空");
        }

        //创建oss实例
        OSS ossClient = CreateOssClient();

        //当bucket不存在的时候创建bucket
        if (!ossClient.doesBucketExist(ConstantYml.BUCKETNAME)){
            createbucket();
        }

        //获取文件名
        String filename = file.getOriginalFilename();
        // 获取文件扩展名
        String extention = filename.substring(filename.lastIndexOf(".")).toLowerCase();
//        if (!".jpg".equals(extention) && !".png".equals(extention) && !".jpeg".equals(extention)) {
//            log.error("文件而非规定格式,检查到的后缀为 -->："+extention+"，如果有误请检查工具类OssUploadTemplate/uploadFileObjectStorage方法  ->>");
//            return ResultResponse.FAILED("文件而非规定格式,请仔细检查");
//        }

        //从公开类获取参数
        String endpoint = ConstantYml.ENDPOINT;
        String bucketName = ConstantYml.BUCKETNAME;

        InputStream inputStream = null;
        String url = "";
        try {
            //获取上传文件输入流
            inputStream = file.getInputStream();

            //生成新的文件名称
            String newName = UUID.randomUUID().toString() + extention;
            log.info("生成新的的文件名为--->：" + newName);


            //调用oss方法实现上传  第一个参数  bucketName 名称 第二个参数  上传到oss的路径  第三个参数，文件输入流
            ossClient.putObject(bucketName, newName, inputStream);

            //构成返回的名称
            url = "https://" + bucketName + "." + endpoint + "/" + newName;

            //关闭流
            inputStream.close();
            return ResultResponse.SUCCESS(200,"上传成功",url);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient。
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return ResultResponse.FAILED();
    }

    /** 根据文件名称删除文件 */
    public ResultResponse deleteFileObjectStorage(String filename) {
        OSS ossClient = CreateOssClient();
        //第一个参数是bucketName,   第二个是文件名称
        ossClient.deleteObject(ConstantYml.BUCKETNAME, filename);
        log.info("进行删除，删除的文件名称是  ->："+filename);
        return ResultResponse.SUCCESS();
    }

    /**
     * @description 下载图片
     * @params [filename]
     * @return com.john.utils.ResultResponse
     * @author -还怕大雨吗
     * @date 2021/8/18 9:32
     */
    public ResultResponse downloadObjectStorage(String filename) {
        //获取文件名
        String objectName = filename.substring(filename.lastIndexOf("/")).toLowerCase().substring(1);

        //创建oss实例
        OSS ossClient = CreateOssClient();

        // 填写不包含Bucket名称在内的Object完整路径，例如testfolder/exampleobject.txt。
        log.info("当前拉取下载的图片名称为  ->："+objectName);

        //判断bucket 里是否存在这个图片
        boolean b = ossClient.doesObjectExist(ConstantYml.BUCKETNAME, objectName);
        if (!b){
            log.error("需要下载的文件不存在，请去控制台检查 --->  ："+objectName);
            return ResultResponse.FAILED("文件不存在，请检查控制台");
        }
        // 下载Object到本地文件，并保存到指定的本地路径中。如果指定的本地文件存在会覆盖，不存在则新建。
        // 如果未指定本地路径，则下载后的文件默认保存到示例程序所属项目对应本地路径中。
        ossClient.getObject(new GetObjectRequest(ConstantYml.BUCKETNAME, objectName), new File(LOCAL_PATH+objectName));
        // 关闭OSSClient。
        ossClient.shutdown();
        return ResultResponse.SUCCESS();
    }

    /**
     * @description 创建buckname
     * @params []
     * @return void
     * @author -还怕大雨吗
     * @date 2021/8/18 10:08
     */
    public void createbucket(){
        //创建oss实例
        OSS ossClient = CreateOssClient();

        CreateBucketRequest bucketRequest = new CreateBucketRequest(null);
        bucketRequest.setBucketName(ConstantYml.BUCKETNAME);
        bucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
        //提交
        ossClient.createBucket(bucketRequest);
        log.info("bucketRequest创建成功,创建的名称是 -> :"+ConstantYml.BUCKETNAME);
    }
}
